 /**    
  *******************************************************************************************************   
  * @attention    
  * Copyright (c) 2023, SHANGHAI FUDAN MICROELECTRONICS GROUP CO., LTD.(FUDAN MICROELECTRONICS./ FUDAN MICRO.)    
  * All rights reserved.    
  *    
  * Processor:                   FM33FG0xxA    
  * http:                        http://www.fmdevelopers.com.cn/    
  *    
  * Redistribution and use in source and binary forms, with or without    
  * modification, are permitted provided that the following conditions are met    
  *    
  * 1. Redistributions of source code must retain the above copyright notice,    
  *    this list of conditions and the following disclaimer.    
  *    
  * 2. Redistributions in binary form must reproduce the above copyright notice,    
  *    this list of conditions and the following disclaimer in the documentation    
  *    and/or other materials provided with the distribution.    
  *    
  * 3. Neither the name of the copyright holder nor the names of its contributors    
  *    may be used to endorse or promote products derived from this software    
  *    without specific prior written permission.    
  *    
  * 4. To provide the most up-to-date information, the revision of our documents     
  *    on the World Wide Web will be the most Current. Your printed copy may be      
  *    an earlier revision. To verify you have the latest information avaliable,    
  *    refer to: http://www.fmdevelopers.com.cn/.    
  *    
  * THIS SOFTWARE IS PROVIDED BY FUDAN MICRO "AS IS" AND ANY EXPRESSED:     
  * ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES     
  * OF MERCHANTABILITY NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE    
  * ARE DISCLAIMED.IN NO EVENT SHALL FUDAN MICRO OR ITS CONTRIBUTORS BE LIABLE     
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL     
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS     
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER    
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,     
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY WAY OUT OF THE     
  * USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE.  
  *
  ******************************************************************************************************* 
  */ 

#include "canfd.h"
#include "fm33fg0xxa_fl.h"
#include "string.h"
#include "fm33fg0xxa.h"
#include "IF_Switch.h"
#include "crc.h"

static const uint8_t dlc_to_wordLength[16] = {0, 1, 1, 1, 1, 2, 2, 2, 2, 3,  4,  5,  6,  8,  12, 16};
CanTxMsg TxMessage = {0};  /* 发送缓冲区 */
CanRxMsg RxMessage = {0};  /* 接收缓冲区 */
VCU_202_FRM VCU_202_Msg;
GSM_308_FRM GSM_308_Msg;
ESC_214_FRM ESC_214_Msg;
uint8_t VCU_101_Data[16];

/* 中断服务函数 */
void CANFD1_IRQHandler(void)
{
    if (FL_CANFD_CH0_IsActiveFlag_BusOffRecovery(CANFD1) &&
        FL_CANFD_CH0_IsEnabledIT_BusOffRecovery(CANFD1))/* BusOff恢复 */
    {
        FL_CANFD_CH0_ClearFlag_BusOffRecovery(CANFD1);
    }
    
    if (FL_CANFD_CH0_IsActiveFlag_BusOff(CANFD1) &&
        FL_CANFD_CH0_IsEnabledIT_BusOff(CANFD1))/* BusOff触发 */
    {
        FL_CANFD_CH0_ClearFlag_BusOff(CANFD1);
    }

    if (FL_CANFD_CH0_IsActiveFlag_ErrorPassive(CANFD1) &&
        FL_CANFD_CH0_IsEnabledIT_ErrorPassive(CANFD1))/* 被动错误 */
    {
        FL_CANFD_CH0_ClearFlag_ErrorPassive(CANFD1);
    }

    if (FL_CANFD_CH0_IsActiveFlag_ErrorWarning(CANFD1) &&
        FL_CANFD_CH0_IsEnabledIT_ErrorWarning(CANFD1))/* 错误提醒 */
    {
        FL_CANFD_CH0_ClearFlag_ErrorWarning(CANFD1);
    }

    if (FL_CANFD_CH0_IsActiveFlag_BusError(CANFD1) &&
        FL_CANFD_CH0_IsEnabledIT_BusError(CANFD1))/* 总线错误 */
    {
        FL_CANFD_CH0_ClearFlag_BusError(CANFD1);        
    }
    
    /* RxMB接收中断 */
    if (FL_CANFD_Global_IsActiveFlag_RxMBNewData(CANFD1, FL_CANFD_RXMB0) &&
        FL_CANFD_Global_IsEnabledIT_RxMB(CANFD1, FL_CANFD_RXMB0))
    {
        FL_CANFD_Global_ClearFlag_RxMBNewData(CANFD1, FL_CANFD_RXMB0);
        FL_CAN_Rx_Read(CANFD1, RX_TYPE_RXMB, FL_CANFD_RXMB0);
    }
    if (FL_CANFD_Global_IsActiveFlag_RxMBNewData(CANFD1, FL_CANFD_RXMB1) &&
        FL_CANFD_Global_IsEnabledIT_RxMB(CANFD1, FL_CANFD_RXMB1))
    {
        FL_CANFD_Global_ClearFlag_RxMBNewData(CANFD1, FL_CANFD_RXMB1);
        FL_CAN_Rx_Read(CANFD1, RX_TYPE_RXMB, FL_CANFD_RXMB1);
    }
    if (FL_CANFD_Global_IsActiveFlag_RxMBNewData(CANFD1, FL_CANFD_RXMB2) &&
        FL_CANFD_Global_IsEnabledIT_RxMB(CANFD1, FL_CANFD_RXMB2))
    {
        FL_CANFD_Global_ClearFlag_RxMBNewData(CANFD1, FL_CANFD_RXMB2);
        FL_CAN_Rx_Read(CANFD1, RX_TYPE_RXMB, FL_CANFD_RXMB2);
    }
    /* RxFIFO接收中断 */
    if (FL_CANFD_Global_IsActiveFlag_RxFIFO(CANFD1, FL_CANFD_RXFIFO0) &&
        FL_CANFD_Global_IsEnabledIT_RxFIFO(CANFD1, FL_CANFD_RXFIFO0))
    {
        FL_CANFD_Global_ClearFlag_RxFIFO(CANFD1, FL_CANFD_RXFIFO0);
        
        FL_CAN_Rx_Read(CANFD1, RX_TYPE_RXFIFO, FL_CANFD_RXFIFO0);
    }
    if (FL_CANFD_Global_IsActiveFlag_RxFIFO(CANFD1, FL_CANFD_RXFIFO1) &&
        FL_CANFD_Global_IsEnabledIT_RxFIFO(CANFD1, FL_CANFD_RXFIFO1))
    {
        FL_CANFD_Global_ClearFlag_RxFIFO(CANFD1, FL_CANFD_RXFIFO1);
        
        FL_CAN_Rx_Read(CANFD1, RX_TYPE_RXFIFO, FL_CANFD_RXFIFO1);
    }

    /* CommonFIFO接收中断 */
    if (FL_CANFD_Global_IsActiveFlag_CommonFIFORx(CANFD1) &&
        FL_CANFD_Global_IsEnabledIT_CommonFIFORx(CANFD1))
    {
        FL_CANFD_Global_ClearFlag_CommonFIFORx(CANFD1);
        
        FL_CAN_Rx_Read(CANFD1, RX_TYPE_COMMONFIFO, 0);
    }    
        
    /* TxMB发送中断 */
    if (FL_CANFD_Global_IsActiveFlag_TotalTxMBTxCompletionStatus(CANFD1, FL_CANFD_TXMB0) &&
        FL_CANFD_Global_IsEnabledIT_TxMB(CANFD1, FL_CANFD_TXMB0))
    {
        FL_CANFD_Global_ClearFlag_TxMBTxResult(CANFD1, FL_CANFD_TXMB0);
    }
}

FL_ErrorStatus Can_Init(CANFD_COMMON_Type *CANFDx)
{
    FL_GPIO_InitTypeDef     GPIO_InitStruct = {0};
    FL_CANFD_InitTypeDef    CANFD_InitStructure = {0};
    FL_ErrorStatus status = FL_PASS;
    
    /* 引脚配置 */
    if (CANFDx == CANFD0)
    {
        /* Rx */
        GPIO_InitStruct.pin = FL_GPIO_PIN_6;
        GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
        GPIO_InitStruct.pull = FL_GPIO_BOTH_DISABLE;
        GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
        GPIO_InitStruct.remapPin = FL_GPIO_PINREMAP_FUNCTON2;
        GPIO_InitStruct.driveStrength = FL_GPIO_DRIVESTRENGTH_X3;  
        (void)FL_GPIO_Init(GPIOE, &GPIO_InitStruct);

        /* Tx */
        GPIO_InitStruct.pin = FL_GPIO_PIN_7;
        GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
        GPIO_InitStruct.pull = FL_GPIO_BOTH_DISABLE;
        GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
        GPIO_InitStruct.remapPin = FL_GPIO_PINREMAP_FUNCTON2;
        GPIO_InitStruct.driveStrength = FL_GPIO_DRIVESTRENGTH_X3;  
        (void)FL_GPIO_Init(GPIOE, &GPIO_InitStruct);
    }
    else if (CANFDx == CANFD1)
    {
        /* Rx */
        GPIO_InitStruct.pin = FL_GPIO_PIN_4;
        GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
        GPIO_InitStruct.pull = FL_GPIO_BOTH_DISABLE;
        GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
        GPIO_InitStruct.remapPin = FL_GPIO_PINREMAP_FUNCTON0;
        GPIO_InitStruct.driveStrength = FL_GPIO_DRIVESTRENGTH_X3;  
        (void)FL_GPIO_Init(GPIOE, &GPIO_InitStruct);

        /* Tx */
        GPIO_InitStruct.pin = FL_GPIO_PIN_8;
        GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
        GPIO_InitStruct.pull = FL_GPIO_BOTH_DISABLE;
        GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
        GPIO_InitStruct.remapPin = FL_GPIO_PINREMAP_FUNCTON0;
        GPIO_InitStruct.driveStrength = FL_GPIO_DRIVESTRENGTH_X3;  
        (void)FL_GPIO_Init(GPIOE, &GPIO_InitStruct);       
    }
    
    /* CAN收发模块引脚使能 */
    FL_GPIO_ResetOutputPin(GPIOG, FL_GPIO_PIN_2);
    GPIO_InitStruct.pin = FL_GPIO_PIN_2;
    GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
    GPIO_InitStruct.pull = FL_GPIO_BOTH_DISABLE;
    GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.remapPin = FL_GPIO_PINREMAP_FUNCTON0;
    GPIO_InitStruct.driveStrength = FL_GPIO_DRIVESTRENGTH_X3;  
    (void)FL_GPIO_Init(GPIOG, &GPIO_InitStruct);

    /* 配置CANFD初始化参数 */
    CANFD_InitStructure.globalMode = FL_CANFD_GLOBAL_MODE_OPERATION;
    CANFD_InitStructure.channelMode = FL_CANFD_CHANNEL_MODE_OPERATION;
    
    /* 32MHz 500K 2000K 4分频/4分频 SJW=3Tq，TS2=4Tq，TS1=11Tq */
    CANFD_InitStructure.NB_SJW = 2; /* 标称位速率配置 */
    CANFD_InitStructure.NB_TS1 = 10;
    CANFD_InitStructure.NB_TS2 = 3;
    CANFD_InitStructure.NB_BRP = 3;
    CANFD_InitStructure.DB_SJW = 2; /* 数据位速率配置 */
    CANFD_InitStructure.DB_TS1 = 10;
    CANFD_InitStructure.DB_TS2 = 3;
    CANFD_InitStructure.DB_BRP = 0;
    
    if (CANFDx == CANFD0)   /* 通信时钟和RAM时钟选择 */
    {
        CANFD_InitStructure.clockSource = FL_CMU_CANFD0_CLK_SOURCE_PLL;
        CANFD_InitStructure.clockSourceRAM = FL_CMU_CANFD0_CLK_SOURCE_RAM_PLL_VCO;
    }
    else if (CANFDx == CANFD1)
    {
        CANFD_InitStructure.clockSource = FL_CMU_CANFD1_CLK_SOURCE_PLL;
        CANFD_InitStructure.clockSourceRAM = FL_CMU_CANFD1_CLK_SOURCE_RAM_PLL_VCO;
    }
    
    /* RxMB配置 */
    // CANFD_InitStructure.rxmbCfg.payloadDataSize = FL_CANFD_RMPLS_SIZE_24;
    // CANFD_InitStructure.rxmbCfg.rxmbNum = 1;
    CANFD_InitStructure.rxmbCfg.payloadDataSize = FL_CANFD_RMPLS_SIZE_32;
    CANFD_InitStructure.rxmbCfg.rxmbNum = 3;
    /* RxFIFO配置 */
    CANFD_InitStructure.rxfifoCfg[0].intGenCounterValue = FL_CANFD_RFIGCV_FULL;
    CANFD_InitStructure.rxfifoCfg[0].intMode = FL_CANFD_RFIM_EVERY_MESSAGE;
    CANFD_InitStructure.rxfifoCfg[0].fifoDepth = FL_CANFD_RFDC_DEPTH_8;
    CANFD_InitStructure.rxfifoCfg[0].payloadDataSize = FL_CANFD_RFPLS_SIZE_24;
    CANFD_InitStructure.rxfifoCfg[0].intEnable = FL_ENABLE;
    CANFD_InitStructure.rxfifoCfg[0].Enable = FL_ENABLE;
    
    CANFD_InitStructure.rxfifoCfg[1].intGenCounterValue = FL_CANFD_RFIGCV_FULL;
    CANFD_InitStructure.rxfifoCfg[1].intMode = FL_CANFD_RFIM_EVERY_MESSAGE;
    CANFD_InitStructure.rxfifoCfg[1].fifoDepth = FL_CANFD_RFDC_DEPTH_8;
    CANFD_InitStructure.rxfifoCfg[1].payloadDataSize = FL_CANFD_RFPLS_SIZE_24;
    CANFD_InitStructure.rxfifoCfg[1].intEnable = FL_ENABLE;
    CANFD_InitStructure.rxfifoCfg[1].Enable = FL_ENABLE;
    /* CommonFIFO配置 */
    CANFD_InitStructure.commonfifoCfg.txInterval = 0;
    CANFD_InitStructure.commonfifoCfg.fifoDepth = FL_CANFD_CFDC_DEPTH_8;
    CANFD_InitStructure.commonfifoCfg.txmbLink = FL_CANFD_CFTML_TXMB3;
    CANFD_InitStructure.commonfifoCfg.intGenCounterValue = FL_CANFD_CFIGCV_FULL;
    CANFD_InitStructure.commonfifoCfg.intMode = FL_CANFD_CFIM_EVERY_MESSAGE;
    CANFD_InitStructure.commonfifoCfg.intervalTimerResolution = FL_CANFD_CFITR_REF_CLOCK_MUL_1;
    CANFD_InitStructure.commonfifoCfg.intervalTimerSource = FL_CANFD_CFITSS_REF_CLOCK;
    CANFD_InitStructure.commonfifoCfg.fifoMode = FL_CANFD_CFM_RX_FIFO;
    CANFD_InitStructure.commonfifoCfg.payloadDataSize = FL_CANFD_CFPLS_SIZE_8;
    CANFD_InitStructure.commonfifoCfg.intEnable = FL_ENABLE;
    CANFD_InitStructure.commonfifoCfg.Enable = FL_ENABLE;
    
    /* TxQueue配置 */
    CANFD_InitStructure.txqueueCfg.queueDepth = FL_CANFD_TXQDC_DEPTH_3;
    CANFD_InitStructure.txqueueCfg.intMode = FL_CANFD_TXQIM_EVERY_TRANSMISSION;
    CANFD_InitStructure.txqueueCfg.intEnable = FL_DISABLE;
    CANFD_InitStructure.txqueueCfg.Enable = FL_DISABLE;
    /* TxHistoryList配置 */
    CANFD_InitStructure.txHistoryCfg.dedicatedTxEnable = FL_ENABLE;
    CANFD_InitStructure.txHistoryCfg.intMode = FL_CANFD_THLIM_EVERY_TRANSMISSION;
    CANFD_InitStructure.txHistoryCfg.intEnable = FL_DISABLE;
    CANFD_InitStructure.txHistoryCfg.Enable = FL_DISABLE;
    
    /* 接收滤波器配置RMB0 */
    CANFD_InitStructure.acceptanceFilterRuleNum = 1;    
    CANFD_InitStructure.acceptanceFilterCfg[0].filterIDE = FL_CANFD_GAFL_IDE_STANDARD;
    CANFD_InitStructure.acceptanceFilterCfg[0].filterRTR = FL_CANFD_GAFL_RTR_DATA_FRAME;
    CANFD_InitStructure.acceptanceFilterCfg[0].filterID = 0x202;
    CANFD_InitStructure.acceptanceFilterCfg[0].filterIDEMask = FL_CANFD_GAFL_IDEM_CONSIDERED;
    CANFD_InitStructure.acceptanceFilterCfg[0].filterRTRMask = FL_CANFD_GAFL_RTRM_CONSIDERED;
    CANFD_InitStructure.acceptanceFilterCfg[0].filterIDMask = 0x1FFFFFFA;//0x1FFFFFFF;
    CANFD_InitStructure.acceptanceFilterCfg[0].rxmbValid = FL_CANFD_GAFL_SINGLE_RXMB_VALID;
    CANFD_InitStructure.acceptanceFilterCfg[0].rxmbNum = FL_CANFD_RXMB0;
    CANFD_InitStructure.acceptanceFilterCfg[0].dlc = 24;
    CANFD_InitStructure.acceptanceFilterCfg[0].commonfifoRecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[0].rxfifo0RecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[0].rxfifo1RecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[0].filterEnable = FL_ENABLE;
    
    /* 接收滤波器配置RMB1 */
    CANFD_InitStructure.acceptanceFilterRuleNum = 2;    
    CANFD_InitStructure.acceptanceFilterCfg[1].filterIDE = FL_CANFD_GAFL_IDE_STANDARD;
    CANFD_InitStructure.acceptanceFilterCfg[1].filterRTR = FL_CANFD_GAFL_RTR_DATA_FRAME;
    CANFD_InitStructure.acceptanceFilterCfg[1].filterID = 0x101;
    CANFD_InitStructure.acceptanceFilterCfg[1].filterIDEMask = FL_CANFD_GAFL_IDEM_CONSIDERED;
    CANFD_InitStructure.acceptanceFilterCfg[1].filterRTRMask = FL_CANFD_GAFL_RTRM_CONSIDERED;
    CANFD_InitStructure.acceptanceFilterCfg[1].filterIDMask = 0x1FFFFFFF;//0x1FFFFFFF;
    CANFD_InitStructure.acceptanceFilterCfg[1].rxmbValid = FL_CANFD_GAFL_SINGLE_RXMB_VALID;
    CANFD_InitStructure.acceptanceFilterCfg[1].rxmbNum = FL_CANFD_RXMB1;
    CANFD_InitStructure.acceptanceFilterCfg[1].dlc = 0;
    CANFD_InitStructure.acceptanceFilterCfg[1].commonfifoRecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[1].rxfifo0RecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[1].rxfifo1RecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[1].filterEnable = FL_ENABLE;

    /* 接收滤波器配置RMB2 */
    CANFD_InitStructure.acceptanceFilterRuleNum = 3;    
    CANFD_InitStructure.acceptanceFilterCfg[2].filterIDE = FL_CANFD_GAFL_IDE_STANDARD;
    CANFD_InitStructure.acceptanceFilterCfg[2].filterRTR = FL_CANFD_GAFL_RTR_DATA_FRAME;
    CANFD_InitStructure.acceptanceFilterCfg[2].filterID = 0x214;
    CANFD_InitStructure.acceptanceFilterCfg[2].filterIDEMask = FL_CANFD_GAFL_IDEM_CONSIDERED;
    CANFD_InitStructure.acceptanceFilterCfg[2].filterRTRMask = FL_CANFD_GAFL_RTRM_CONSIDERED;
    CANFD_InitStructure.acceptanceFilterCfg[2].filterIDMask = 0x214;//0x1FFFFFFF;
    CANFD_InitStructure.acceptanceFilterCfg[2].rxmbValid = FL_CANFD_GAFL_SINGLE_RXMB_VALID;
    CANFD_InitStructure.acceptanceFilterCfg[2].rxmbNum = FL_CANFD_RXMB2;
    CANFD_InitStructure.acceptanceFilterCfg[2].dlc = 0;
    CANFD_InitStructure.acceptanceFilterCfg[2].commonfifoRecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[2].rxfifo0RecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[2].rxfifo1RecvEnable = FL_DISABLE;
    CANFD_InitStructure.acceptanceFilterCfg[2].filterEnable = FL_ENABLE;
    
    /* 特殊参数配置 */
    CANFD_InitStructure.txPriority = FL_CANFD_TX_PRIORITY_ID;   /* 发送优先级 */    
    CANFD_InitStructure.esiCfg = FL_CANFD_ESI_CONFIGURATION_SOFTWARE; /* ESI配置 */
    CANFD_InitStructure.tdco = 12; /* TDCO配置，其等于同步段+传输段+相位1 */
    CANFD_InitStructure.tdcoCfg = FL_CANFD_TDCO_CONFIGURATION_MEASURED_WITH_OFFSET;/* TDCO模式配置 */
    CANFD_InitStructure.tdcoEnable = FL_ENABLE;
    CANFD_InitStructure.respedEnable = FL_ENABLE;
    CANFD_InitStructure.dlcCheckEnable = FL_DISABLE;
    CANFD_InitStructure.dlcReplacementEnable = FL_DISABLE;
    CANFD_InitStructure.messageIsRejected = FL_ENABLE;
    
    status = FL_CANFD_Init(CANFDx, &CANFD_InitStructure);
    
    /* 中断配置 */
    /* 异常中断配置 */
    FL_CANFD_CH0_ClearFlag_BusOffRecovery(CANFDx); /* bus-off恢复 bus-off出现 被动错误出现 错误提醒 总线错误 */
    FL_CANFD_CH0_ClearFlag_BusOff(CANFDx);
    FL_CANFD_CH0_ClearFlag_ErrorPassive(CANFDx);
    FL_CANFD_CH0_ClearFlag_ErrorWarning(CANFDx);
    FL_CANFD_CH0_ClearFlag_BusError(CANFDx);
    FL_CANFD_CH0_EnableIT_BusOffRecovery(CANFDx);
    FL_CANFD_CH0_EnableIT_BusOff(CANFDx);
    FL_CANFD_CH0_EnableIT_ErrorPassive(CANFDx);
    FL_CANFD_CH0_EnableIT_ErrorWarning(CANFDx);
    FL_CANFD_CH0_EnableIT_BusError(CANFDx);

    /* 接收RM中断配置 */
    FL_CANFD_Global_ClearFlag_RxMBNewData(CANFDx, FL_CANFD_RXMB0);
    FL_CANFD_Global_ClearFlag_RxMBNewData(CANFDx, FL_CANFD_RXMB1);
    FL_CANFD_Global_ClearFlag_RxMBNewData(CANFDx, FL_CANFD_RXMB2);
    FL_CANFD_Global_ClearFlag_RxFIFO(CANFDx, FL_CANFD_RXFIFO0);
    FL_CANFD_Global_ClearFlag_CommonFIFORx(CANFDx);
    FL_CANFD_Global_EnableIT_RxMB(CANFDx, FL_CANFD_RXMB0);
    FL_CANFD_Global_EnableIT_RxMB(CANFDx, FL_CANFD_RXMB1);
    FL_CANFD_Global_EnableIT_RxMB(CANFDx, FL_CANFD_RXMB2);
    FL_CANFD_Global_EnableIT_RxFIFO(CANFDx, FL_CANFD_RXFIFO0);
    FL_CANFD_Global_EnableIT_CommonFIFORx(CANFDx);
    /* 发送TM中断配置 */
    FL_CANFD_Global_ClearFlag_TxMBTxResult(CANFDx, FL_CANFD_TXMB0);
    FL_CANFD_Global_EnableIT_TxMB(CANFDx, FL_CANFD_TXMB0);
    
    if (CANFDx == CANFD0)
    {
        NVIC_DisableIRQ(CANFD0_IRQn);
        NVIC_SetPriority(CANFD0_IRQn, 2);
        NVIC_EnableIRQ(CANFD0_IRQn);        
    }
    else
    {
        NVIC_DisableIRQ(CANFD1_IRQn);
        NVIC_SetPriority(CANFD1_IRQn, 2);
        NVIC_EnableIRQ(CANFD1_IRQn);
    }
    
    return status;
}

/* 通过TX Buffer发送数据 */
void FL_CAN_BUFFER_Write(CANFD_COMMON_Type *CANFDx, CanTxMsg *TxMesg)
{
    uint32_t index, i;
    uint32_t counter = 0;
    uint32_t TXReady = 0;
    
    CANFD_TX_MESSAGE_Type *p_TX_MESSAGE = CANFD_BUFFER[CANFD_NUM(CANFDx)].TX_MESSAGE;
    CANFD_COMMON_FIFO_Type *p_COMMON_FIFO = CANFD_BUFFER[CANFD_NUM(CANFDx)].COMMON_FIFO;

    index = TxMesg->TxNum;
    
    switch (TxMesg->TxType)
    {
        case TX_TYPE_TXMB:
            if (index >= FL_CANFD_TXMB_MAX)
            {
                return;
            }
            
            /* 判断TxMB是否被TxQueue占用 */
            if ((FL_CANFD_Global_GetTxQueueDepth(CANFDx) == FL_CANFD_TXQDC_DEPTH_4) ||\
                ((FL_CANFD_Global_GetTxQueueDepth(CANFDx) == FL_CANFD_TXQDC_DEPTH_3) && (index != FL_CANFD_TXMB3)))
            {
                return;
            }
            /* 判断TxMB是否被CommonFIFO占用 */
            if ((FL_CANFD_Global_GetCommonFIFOMode(CANFDx) == FL_CANFD_CFM_TX_FIFO) &&\
                (FL_CANFD_Global_GetCommonFIFOTxMBLink(CANFDx) == (TxMesg->TxNum << CANFD_CFDCFCC_CFTML_Pos)))
            {
                return;
            }
            
            /* TxMB发送空闲才可以发送 */
            do
            {
                if (!FL_CANFD_Global_IsActiveFlag_TxMBTxStatus(CANFDx, index))
                {
                    TXReady = 0x01;
                }
                counter++;
            }
            while ((0x01U != TXReady) && (counter != CAN_TIMEOUT));
            
            FL_CANFD_Global_ClearFlag_TxMBTxResult(CANFDx, index);
            
            /* 写入Buffer */
            p_TX_MESSAGE->CFDTM[index].CFDTMIDb = TxMesg->ID;
            p_TX_MESSAGE->CFDTM[index].CFDTMPTRb = TxMesg->PTR;
            p_TX_MESSAGE->CFDTM[index].CFDTMFDCTRb = TxMesg->FDCTR;                
            for (i = 0; i < dlc_to_wordLength[(TxMesg->PTR & CANFD_CFDTMPTR_TMDLC_Msk) >> CANFD_CFDTMPTR_TMDLC_Pos]; i++)
            {
                p_TX_MESSAGE->CFDTM[index].CFDTMDFbp[i] = TxMesg->Data.Data32[i];
            }
            
            FL_CANFD_Global_SetTxMBOneshotMode(CANFDx, index, TxMesg->OneShot);
            FL_CANFD_Global_Enable_TxMBTxRequest(CANFDx, index);
            break;
        case TX_TYPE_COMMONFIFO:
            /* 判断CommonFIFO模式及使能状态 */
            if ((FL_CANFD_Global_IsEnabled_CommonFIFO(CANFDx) != FL_ENABLE) ||\
                (FL_CANFD_Global_GetCommonFIFOMode(CANFDx) != FL_CANFD_CFM_TX_FIFO))
            {
                return;
            }
            
            /* 判断TxMB是否被TxQueue占用 */
            if ((FL_CANFD_Global_GetTxQueueDepth(CANFDx) == FL_CANFD_TXQDC_DEPTH_4) ||\
                ((FL_CANFD_Global_GetTxQueueDepth(CANFDx) == FL_CANFD_TXQDC_DEPTH_3) && (FL_CANFD_Global_GetCommonFIFOTxMBLink(CANFDx) != FL_CANFD_CFTML_TXMB3)))
            {
                return;
            }
            
            /* CommonFIFO不满才可以发送 */
            do
            {
                if (!FL_CANFD_Global_IsActiveFlag_CommonFIFOFull(CANFDx))
                {
                    TXReady = 0x01;
                }
                counter++;
            }
            while ((0x01U != TXReady) && (counter != CAN_TIMEOUT));        

            p_COMMON_FIFO->CFDCFID = TxMesg->ID;
            p_COMMON_FIFO->CFDCFPTR = TxMesg->PTR;
            p_COMMON_FIFO->CFDCFFDCSTS = TxMesg->FDCTR;            
            for (i = 0; i < dlc_to_wordLength[(TxMesg->PTR & CANFD_CFDCFPTR_CFDLC_Msk) >> CANFD_CFDCFPTR_CFDLC_Pos]; i++)
            {
                p_COMMON_FIFO->CFDCFDFp[i] = TxMesg->Data.Data32[i];
            }            

            FL_CANFD_Global_WriteCommonFIFOPointer(CANFDx, 0xFF);
            break;
        case TX_TYPE_QUEUE:
            /* 判断TxQueue模式及使能状态 */
            if ((FL_CANFD_Global_IsEnabled_TxQueue(CANFDx) != FL_ENABLE) ||\
                (FL_CANFD_Global_GetTxQueueDepth(CANFDx) == FL_CANFD_TXQDC_DEPTH_0))
            {
                return;
            }           
            
            /* 判断TxMB是否被CommonFIFO占用 */
            if (FL_CANFD_Global_GetCommonFIFOMode(CANFDx) == FL_CANFD_CFM_TX_FIFO)
            {
                if ((FL_CANFD_Global_GetTxQueueDepth(CANFDx) == FL_CANFD_TXQDC_DEPTH_4) ||\
                    ((FL_CANFD_Global_GetTxQueueDepth(CANFDx) == FL_CANFD_TXQDC_DEPTH_3) && (FL_CANFD_Global_GetCommonFIFOTxMBLink(CANFDx) != FL_CANFD_CFTML_TXMB3)))
                {
                    return;
                }
            }
            
            /* 队列不满才可以发送 */
            do
            {
                if (!FL_CANFD_Global_IsActiveFlag_TxQueueFull(CANFDx))
                    
                {
                    TXReady = 0x01;
                }
                counter++;
            }
            while ((0x01U != TXReady) && (counter != CAN_TIMEOUT));    
            
            p_TX_MESSAGE->CFDTM[0].CFDTMIDb = TxMesg->ID;
            p_TX_MESSAGE->CFDTM[0].CFDTMPTRb = TxMesg->PTR;
            p_TX_MESSAGE->CFDTM[0].CFDTMFDCTRb = TxMesg->FDCTR;            
            for (i = 0; i < dlc_to_wordLength[(TxMesg->PTR & CANFD_CFDTMPTR_TMDLC_Msk) >> CANFD_CFDTMPTR_TMDLC_Pos]; i++)
            {
                p_TX_MESSAGE->CFDTM[0].CFDTMDFbp[i] = TxMesg->Data.Data32[i];
            }
            
            FL_CANFD_Global_WriteTxQueuePointer(CANFDx, 0xFF);
            break;
        default:
            break;
    }
}

/* Rx读取 */
void FL_CAN_Rx_Read(CANFD_COMMON_Type *CANFDx, uint8_t RxType, uint8_t Num)
{
    uint32_t i;
    volatile uint8_t MsgDlc = 0;
    
    switch (RxType)
    {
        case RX_TYPE_RXMB:
            if (Num < FL_CANFD_RXMB_MAX)
            {
                RxMessage.ID = RM(CANFDx, Num).CFDRMIDb;
                RxMessage.PTR = RM(CANFDx, Num).CFDRMPTRb;
                RxMessage.FDSTS = RM(CANFDx, Num).CFDRMFDSTSb;                
                for (i = 0; i < dlc_to_wordLength[(RxMessage.PTR & CANFD_CFDRMPTR_RMDLC_Msk) >> CANFD_CFDRMPTR_RMDLC_Pos]; i++)
                {
                    RxMessage.Data.Data32[i] = RM(CANFDx, Num).CFDRMDFbp[i];
                }
                MsgDlc = dlc_to_wordLength[(RxMessage.PTR & CANFD_CFDRMPTR_RMDLC_Msk) >> CANFD_CFDRMPTR_RMDLC_Pos] * 4;
            }
            // TxMessage.ID = CANFD_CFDTMID_THLEN | (0x100000 + RxMessage.ID);    /* 加入THL, 标准ID */
            // FL_CAN_Frame_Send(FL_CANFD_FORMAT_FD_EXTEND_DATA, BRS_ENABLE, &TxMessage, CANFDx);
            if((RxMessage.ID == 0x202) && (MsgDlc == 24))
            {
                VCU_202_Msg.VCU_202_Checksum = (RxMessage.Data.Data32[0] >> 16) & 0xffff;
                VCU_202_Msg.VCU_202_RollingCounter = RxMessage.Data.Data8[2];
                VCU_202_Msg.VCU_DriveReady = RxMessage.Data.Data8[9] & 0x3;
                VCU_202_Msg.VCU_ActualGearValid = (RxMessage.Data.Data8[18] & 0x10) >> 4;
                if((VCU_202_Msg.VCU_DriveReady == 2) & (VCU_202_Msg.VCU_ActualGearValid == 1))
                VCU_202_Msg.VCU_ActualGear = RxMessage.Data.Data8[18] & 0x0f;
            }
            if((RxMessage.ID == 0x101) && (MsgDlc == 16))
            {
                volatile uint16_t crc16 = 0;
                volatile uint8_t datax[16] = {0x0};
                memcpy(datax, RxMessage.Data.Data8+2, 14);
                datax[14] = 0x01; datax[15] = 0x31;
                for(i = 0; i < 16; i++)
                VCU_101_Data[i] = RxMessage.Data.Data8[i];
                crc16 = CRC16_CCITT_FALSE(datax,16);
                
            }            
            if((RxMessage.ID == 0x214) && (MsgDlc == 32))
            {
                uint16_t crc16_1 = 0;
                uint8_t data_esc[32] = {0x0};
                memcpy(data_esc, RxMessage.Data.Data8+2, 30);
                data_esc[30] = 0x14; data_esc[31] = 0x42; 
                crc16_1 = CRC16_CCITT_FALSE(data_esc, 32);                
                ESC_214_Msg.ESC_214_Checksum = (RxMessage.Data.Data32[0] >> 16) & 0xffff;
                ESC_214_Msg.ESC_214_RollingCounter = RxMessage.Data.Data8[2];
                ESC_214_Msg.ESC_VehicleSpeedValid = RxMessage.Data.Data8[21] >> 6;
                if(/*(crc16_1 == ESC_214_Msg.ESC_214_Checksum) && */(ESC_214_Msg.ESC_VehicleSpeedValid))
                {
                    ESC_214_Msg.ESC_VehicleSpeed = (uint16_t)RxMessage.Data.Data8[22] << 8 |  RxMessage.Data.Data8[23];
                }
            }
            break;
        case RX_TYPE_RXFIFO:
            if (Num < FL_CANFD_RXFIFO_MAX)
            {                
                RxMessage.ID = RF(CANFDx, Num).CFDRFIDb;
                RxMessage.PTR = RF(CANFDx, Num).CFDRFPTRb;
                RxMessage.FDSTS = RF(CANFDx, Num).CFDRFFDSTSb;                
                for (i = 0; i < dlc_to_wordLength[(RxMessage.PTR & CANFD_CFDRFPTR_RFDLC_Msk) >> CANFD_CFDRFPTR_RFDLC_Pos]; i++)
                {
                    RxMessage.Data.Data32[i] = RF(CANFDx, Num).CFDRFDFbp[i];
                }
                
                FL_CANFD_Global_WriteRxFIFOPointer(CANFDx, Num, 0xFF);                
            }
            // TxMessage.ID = CANFD_CFDTMID_THLEN | (0x200000 + RxMessage.ID);    /* 加入THL, 标准ID */
            // FL_CAN_Frame_Send(FL_CANFD_FORMAT_FD_EXTEND_DATA, BRS_ENABLE, &TxMessage, CANFDx);
            break;
        case RX_TYPE_COMMONFIFO:
            if (Num == 0)
            {
                RxMessage.ID = CF(CANFDx)->CFDCFID;
                RxMessage.PTR = CF(CANFDx)->CFDCFPTR;
                RxMessage.FDSTS = CF(CANFDx)->CFDCFFDCSTS;                
                for (i = 0; i < dlc_to_wordLength[(RxMessage.PTR & CANFD_CFDCFPTR_CFDLC_Msk) >> CANFD_CFDCFPTR_CFDLC_Pos]; i++)
                {
                    RxMessage.Data.Data32[i] = CF(CANFDx)->CFDCFDFp[i];
                }
                
                FL_CANFD_Global_WriteCommonFIFOPointer(CANFDx, 0xFF);
            }
            // TxMessage.ID = CANFD_CFDTMID_THLEN | (0x300000 + RxMessage.ID);    /* 加入THL, 标准ID */
            // FL_CAN_Frame_Send(FL_CANFD_FORMAT_FD_EXTEND_DATA, BRS_ENABLE, &TxMessage, CANFDx);
            break;
        default:
            break;
    }
    
}

uint8_t Data1[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; /* 要发送的数据 */
/* 数据发送设置 */
void CAN_SetMsg(CanTxMsg *TxMesg)
{
    uint32_t i;
    
    TxMesg->ID = CANFD_CFDTMID_THLEN | 0x308;    /* 加入THL, 标准ID */
    TxMesg->PTR = 8U << CANFD_CFDTMPTR_TMDLC_Pos;
    TxMesg->FDCTR = (0x1234U << CANFD_CFDTMFDCTR_TMPTR_Pos) | (3U << CANFD_CFDTMFDCTR_TMIFL_Pos);
    TxMesg->TxType = TX_TYPE_TXMB;
    TxMesg->TxNum = FL_CANFD_TXMB0;
    TxMesg->OneShot = FL_CANFD_TXMODE_CONTINUOUS;
    
    /* 设置要发送的数据0-7 */
    for (i = 0; i < 8; i++)
    {
        TxMesg->Data.Data8[i] = Data1[i];
    }
}

/* 帧模式选择 */
void FL_CAN_Frame_Send(uint32_t frame_format, uint8_t BRS, CanTxMsg *TxMesg, CANFD_COMMON_Type *CANFDx)
{
    /* 清除原有配置bit */
    TxMesg->ID &= ~(CANFD_CFDTMID_TMIDE_Msk | CANFD_CFDTMID_TMRTR_Msk);
    TxMesg->FDCTR &= ~(CANFD_CFDTMFDCTR_TMFDF_Msk | CANFD_CFDTMFDCTR_TMBRS_Msk);
    
    if (frame_format == FL_CANFD_FORMAT_STANDARD_DATA) /* 标准数据帧 */
    {
        ;
    }
    else if (frame_format == FL_CANFD_FORMAT_STANDARD_REMOTE) /* 标准远程帧 */
    {
        TxMesg->ID |= CANFD_CFDTMID_TMRTR_Msk;
    }
    else if (frame_format == FL_CANFD_FORMAT_EXTEND_DATA) /* 扩展数据帧 */
    {
        TxMesg->ID |= CANFD_CFDTMID_TMIDE_Msk;
    }
    else if (frame_format == FL_CANFD_FORMAT_EXTEND_REMOTE) /* 扩展远程帧 */
    {
        TxMesg->ID |= (CANFD_CFDTMID_TMIDE_Msk | CANFD_CFDTMID_TMRTR_Msk);
    }
    else if (frame_format == FL_CANFD_FORMAT_FD_STANDARD_DATA)/* FD标准数据帧 */
    {
        TxMesg->FDCTR |= CANFD_CFDTMFDCTR_TMFDF_Msk;
    }
    else if (frame_format == FL_CANFD_FORMAT_FD_STANDARD_REMOTE)/* FD标准远程帧 */
    {
        TxMesg->ID |= CANFD_CFDTMID_TMRTR_Msk;
        TxMesg->FDCTR |= CANFD_CFDTMFDCTR_TMFDF_Msk;
    }
    else if (frame_format == FL_CANFD_FORMAT_FD_EXTEND_DATA)/* FD扩展数据帧 */
    {
        TxMesg->ID |= CANFD_CFDTMID_TMIDE_Msk;
        TxMesg->FDCTR |= CANFD_CFDTMFDCTR_TMFDF_Msk;
    }
    else if (frame_format == FL_CANFD_FORMAT_FD_EXTEND_REMOTE)/* FD扩展远程帧 */
    {
        TxMesg->ID |= (CANFD_CFDTMID_TMIDE_Msk | CANFD_CFDTMID_TMRTR_Msk);
        TxMesg->FDCTR |= CANFD_CFDTMFDCTR_TMFDF_Msk;
    }
    
    /* BRS */
    TxMesg->FDCTR &= ~CANFD_CFDTMFDCTR_TMBRS_Msk;
    TxMesg->FDCTR |= (BRS << CANFD_CFDTMFDCTR_TMBRS_Pos);
    
    /* ESI 按实际配置 */

    FL_CAN_BUFFER_Write(CANFDx, TxMesg);
}

void TransmitMsg_0x308(void)
{
    uint8_t puchMsg[8];
    #ifdef _REQ_GEARS_
    switch(MachSt.GearCurState)
    {
        case GEARS_INIT:
            GSM_308_Msg.GSM_ShiftLeverPos = SCU_CAN_TX_GEAR_INIT;
            break;
        case GEARS_P:
            GSM_308_Msg.GSM_ShiftLeverPos = SCU_CAN_TX_GEAR_P;
            break;
        case GEARS_R:
            GSM_308_Msg.GSM_ShiftLeverPos = SCU_CAN_TX_GEAR_R;
            break;
        case GEARS_N:
            GSM_308_Msg.GSM_ShiftLeverPos = SCU_CAN_TX_GEAR_N;
            break;
        case GEARS_D:
            GSM_308_Msg.GSM_ShiftLeverPos = SCU_CAN_TX_GEAR_D;
            break;
        default:
            break;
    }
    #else
    GSM_308_Msg.GSM_ShiftLeverPos = IF_GetShiftLevelPos();
    #endif
    GSM_308_Msg.GSM_ShifterPosInv = 15U - GSM_308_Msg.GSM_ShiftLeverPos;
    GSM_308_Msg.GSM_ParkButtonSts = IF_Get_CanTx_ParkButtonSts();
    GSM_308_Msg.GSM_PButtonLongPress = IF_Get_PBPButtonLongPress();
    GSM_308_Msg.GSM_ParkButtonSts_VD = IF_Get_CanTx_ParkButtonSts_VD();
    GSM_308_Msg.GSM_Fault = IF_SwitchGetMechErrState();
    Data1[2] = GSM_308_Msg.GSM_308_RollingCounter;
    Data1[3] = GSM_308_Msg.GSM_ShiftLeverPos | GSM_308_Msg.GSM_ShifterPosInv << 4;
    Data1[4] = GSM_308_Msg.GSM_Fault | GSM_308_Msg.GSM_ParkButtonSts_VD << 1 | GSM_308_Msg.GSM_PButtonLongPress << 2 | GSM_308_Msg.GSM_ParkButtonSts << 3;
    Data1[5] = 0; Data1[6] = 0; Data1[7] = 0;
    memcpy(puchMsg, &Data1[2], 6);
    puchMsg[6] = 0x08; puchMsg[7] = 0x43;
    GSM_308_Msg.GSM_308_Checksum = CRC16_CCITT_FALSE(puchMsg, 8);
    Data1[0] = (uint8_t)(GSM_308_Msg.GSM_308_Checksum >> 8);
    Data1[1] = (uint8_t)(GSM_308_Msg.GSM_308_Checksum & 0x00ff);
    
    GSM_308_Msg.GSM_308_RollingCounter++;
    if(GSM_308_Msg.GSM_308_RollingCounter == 0xF) 
    {
        GSM_308_Msg.GSM_308_RollingCounter = 0;
    }
    /* 设置要发送的数据0-7 */
    for (uint8_t i = 0; i < 8; i++)
    {
        TxMessage.Data.Data8[i] = Data1[i];
    }
    FL_CAN_Frame_Send(FL_CANFD_FORMAT_FD_STANDARD_DATA, BRS_ENABLE, &TxMessage, CANFD1);
}

uint16_t IF_GetVehicleSpeed(void)
{
    return ESC_214_Msg.ESC_VehicleSpeed;
}